home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 33
/
Aminet 33 - October 1999.iso
/
Aminet
/
comm
/
misc
/
DigiCam.lha
/
src
/
Goodie
/
seeserial.c
Wrap
C/C++ Source or Header
|
1999-07-14
|
12KB
|
356 lines
/* seeserial.c (c) 1999 by Volker Remuß, remuss@cs.tu-berlin.de */
/* */
/* For LINUX/UNIX. Can be used to link a camera connection through */
/* another computer to listen to the protocol. The complete known */
/* protocol is watched and interpreted. */
/* Since the algorithm is very simple you only see every package if the */
/* next package in the other direction is send. */
/* I used this to spy out the communication between the windowssoftware */
/* and the camera. */
/* */
/* If you want to do this, too. Don't forget to fix the serial speed to */
/* 19200 bps. No other speed is possible, because changes in speed are */
/* not recognized by seeserial. */
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define HOST "/dev/ttyS1"
#define KAMERA "/dev/ttyS2"
#define BPS B19200
int s1fd=-1, s2fd=-1; // Serial1 and Serial2 FDs
struct termios oldtio1, oldtio2;
void myexit(int ret)
{
if (s1fd != -1)
{
tcsetattr(s1fd, TCSANOW, &oldtio1);
close(s1fd);
}
if (s2fd != -1)
{
tcsetattr(s2fd, TCSANOW, &oldtio2);
close(s2fd);
}
exit (ret);
}
void openser()
{
struct termios newtio1, newtio2;
// Open Serial Port 1
s1fd = open(HOST, O_RDWR | O_NOCTTY); // read/write
if (s1fd < 0) {perror(HOST); myexit(-1); }
tcgetattr(s1fd, &oldtio1); // save current settings of serial port 1
// Init Serial Port 1
bzero(&newtio1, sizeof(newtio1));
newtio1.c_cflag = BPS | CS8 | CLOCAL | CREAD;
newtio1.c_iflag = IGNPAR | IGNBRK;
newtio1.c_oflag = 0;
newtio1.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
newtio1.c_cc[VTIME] = 1; /* inter-character timer */
newtio1.c_cc[VMIN] = 0; /* blocking read until x chars received */
tcflush(s1fd, TCIOFLUSH);
tcsetattr(s1fd,TCSANOW,&newtio1);
// Open Serial Port 2
s2fd = open(KAMERA, O_RDWR | O_NOCTTY); // non-blocking read/write
if (s2fd < 0) {perror(KAMERA); myexit(-1); }
tcgetattr(s2fd, &oldtio2); // save current settings of serial port 2
// Init Serial Port 1
bzero(&newtio2, sizeof(newtio2));
newtio2.c_cflag = BPS | CS8 | CLOCAL | CREAD;
newtio2.c_iflag = IGNPAR | IGNBRK;
newtio2.c_oflag = 0;
newtio2.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
newtio2.c_cc[VTIME] = 1; /* inter-character timer */
newtio2.c_cc[VMIN] = 0; /* blocking read until x chars received */
tcflush(s2fd, TCIOFLUSH);
tcsetattr(s2fd,TCSANOW,&newtio2);
}
void cryout (unsigned char *buf, int cnt, char *string)
// output of complete buffer in hex and as far as possible as human readable
{
int i, nochncnt=0;
unsigned char nochnbuf[100];
if (cnt) printf("\nReceived from %s:\n", string);
else return;
for (i=0; i < cnt; i++)
{
printf("%2hx ", buf[i]);
if ((buf[i] >= ' ') && (buf[i] <='~')) // readable character? if not write a . instead
nochnbuf[nochncnt++] = buf[i];
else
nochnbuf[nochncnt++] = '.';
if ((nochncnt) > 11)
{
nochnbuf[nochncnt] = 0;
printf(" %s\n", nochnbuf);
nochncnt = 0;
}
}
if (nochncnt)
{
nochnbuf[nochncnt] = '\0';
for (i=(12-nochncnt); i > 0; i--) printf(" ");
printf(" %s\n", nochnbuf);
nochncnt = 0;
}
}
void interpret(unsigned char *buf, int cnt)
{
if (cnt)
{
if (cnt > 1)
{
if (buf[0] == 0x06)
{
printf("Acknowledged and \n");
buf++;
cnt--;
}
if (buf[0] == 0x15)
{
printf("Not Acknowledged and\n");
buf++;
cnt--;
}
}
switch (cnt)
{
case 1:
switch (buf[0])
{
case 0x00: printf("Initialisation of camera\n"); break;
case 0x05: printf("Action completed\n"); break;
case 0x06: printf("Acknowledged\n"); break;
case 0x15: printf("Not Acknowledged or camera response to init\n"); break;
case 0x11: printf("Unable to Execute Command\n"); break;
case 0xff: printf("Termnination - Camera did an idlereset\n"); break;
default: printf("Unknown one byte packet\n"); break;
}
break;
case 2:
if ((buf[0] == 0x06) && (buf[2] == 0x05))
printf("\n Acknowledged and Action Completed\n");
else
printf("Unknown two bytes packet\n");
break;
default:
switch (buf[0])
{
case 0x02: printf("Data packet that is not last in sequence\n");
printf("Sequence Nr.: %d\n Datalength: %d\n", buf[1], (buf[2] | (buf[3] << 8)));
break;
case 0x03: printf("Data packet that is last in sequence\n");
printf("Sequence Nr.: %d\n Datalength: %d\n", buf[1], (buf[2] | (buf[3] << 8)));
break;
case 0x1b: printf("Command Packet - ");
switch (buf[1])
{
case 0x43: printf("just an ordinary one\n"); break;
case 0x53: printf("the first in session\n"); break;
default: printf("of unknown type\n"); break;
}
printf("Length of command and parameter is: %d\nCommandtype: ", (buf[2] | (buf[3] << 8)));
switch (buf[4])
{
case 0: printf("Set value of integer register"); break;
case 1: printf("Read value of integer register"); break;
case 2: printf("Take action unrelated to registers: "); break;
case 3: printf("Set value of vdata register"); break;
case 4: printf("Read value of vdata register"); break;
default: printf("Unknown type of command"); break;
}
if (buf[4] != 2)
{
printf("\n Register No. %d Type: ", buf[5]);
switch (buf[5])
{
case 1: printf("Resolution"); break;
case 2: printf("Clock"); break;
case 3: printf("Shutter Speed"); break;
case 4: printf("Current Frame Number"); break;
case 5: printf("Aperture"); break;
case 6: printf("Color Mode"); break;
case 7: printf("Flash Mode"); break;
case 10: printf("No. of frames taken"); break;
case 11: printf("No. of frames left"); break;
case 12: printf("Length of current frame"); break;
case 13: printf("Length of current thumbnail"); break;
case 14: printf("Current frame JFIF data"); break;
case 15: printf("Current thumbnail JFIF data"); break;
case 16: printf("Battery Capacity"); break;
case 17: printf("Communication Speed"); break;
case 19: printf("Brightness + Contrast"); break;
case 20: printf("White balance"); break;
case 22: printf("Camera I.D."); break;
case 23: printf("Autoshut on host timer"); break;
case 24: printf("Autoshut in field timer"); break;
case 25: printf("Serial No."); break;
case 26: printf("Version"); break;
case 27: printf("Model"); break;
case 28: printf("Available Memory left"); break;
case 29: printf("Upload image JFIF"); break;
case 30: printf("LED"); break;
case 32: printf("Used before uploading image"); break;
case 33: printf("Lens mode"); break;
case 35: printf("LCD brightness"); break;
case 38: printf("LCD autoshut timer"); break;
case 39: printf("Protection state of current frame"); break;
case 41: printf("LCD date format"); break;
case 44: printf("Audiodata"); break;
case 46: printf("Camera summary data"); break;
case 47: printf("Picture summary data"); break;
case 48: printf("Manufaacturer"); break;
case 70: printf("Exp.meter"); break;
case 72: printf("Bitmap"); break;
default: printf("Unknown No. %d", buf[5]); break;
}
}
else
{
switch (buf[5])
{
case 0: printf("Erase last picture"); break;
case 1: printf("Erase all pictures"); break;
case 2: printf("Take picture"); break;
case 4: printf("Finish session immediately"); break;
case 5: printf("Take preview snapshot"); break;
case 7: printf("Erase current frame"); break;
case 9: printf("Set protection of current frame"); break;
case 11: printf("Store freshly uploaded image inbto NVRAM"); break;
default: printf("Unkown command %d", buf[5]); break;
}
}
printf("\n");
break;
default: printf("Unknown packet type\n");
break;
}
}
}
}
void main(void)
{
int rd1, rd2; // readcounter
unsigned char buf1[2100], buf2[2100]; // Readin - Throwout Buffer for both serials
unsigned char outbuf[100000]; // Buffer for screenoutput to collect uninterrupted chunks of same input data
int outcnt=0; // used to organize outbuf
int lastinput=0; // last serial that got an input
openser();
while (1)
{
if ((rd1=read(s1fd, buf1, 2100)) == -1) // error ?
{
perror("While reading Host");
exit(-1);
}
if (rd1) // got input
{
if ((write(s2fd, buf1, rd1)) != rd1) // foward to other port - error?
{
perror("While writing Kamera");
exit(-1);
}
if ((lastinput != 1) || ((outcnt+rd1) > 100000)) // different port than last input?
{
cryout(outbuf, outcnt, HOST); // yes -> dump buffer to screen
interpret(outbuf, outcnt);
lastinput = 1;
outcnt = 0;
}
// no -> append to outbuffer
/*
if ((outcnt + rd1) > 100000)
{
fprintf(stderr, "Outputbuffer for screendump overflowed\n");
myexit(-1);
}
*/
memcpy(outbuf+outcnt, buf1, rd1);
outcnt += rd1;
}
if ((rd2=read(s2fd, buf2, 2100)) == -1) // error ?
{
perror("While reading Kamera");
exit(-1);
}
if (rd2) // output to other port
{
if ((write(s1fd, buf2, rd2)) != rd2)
{
perror("While writing Host");
exit(-1);
}
if ((lastinput != 2) || ((outcnt+rd2 > 100000))) // different port than last input?
{
cryout(outbuf, outcnt, KAMERA); // yes -> dump buffer to screen
interpret(outbuf, outcnt);
lastinput = 2;
outcnt = 0;
}
// append to outbuffer
/*
if ((outcnt + rd2) > 100000)
{
fprintf(stderr, "Outputbuffer for screendump overflowed\n");
myexit(-1);
}
*/
memcpy(outbuf+outcnt, buf2, rd2);
outcnt += rd2;
}
}
myexit(0);
}